#pragma once
#include <gdiplus.h>
#include "KinectLib.h"
#include "MemoryOpenGL.h"

// class KinectGdiRender
class KinectGdiRender
{
public:
    KinectGdiRender();
    virtual ~KinectGdiRender();

public:
    void setScaleRatio(float ratio);
    // 0 ~ 360
    void setLookAtAngle(float xAngle, float yAngle);
    void drawColorToBitmap(KinectLib *pKinect, int width, int height, const KinectImageFrame &frame, bool drawSkeleton = false);
    void drawDepthToBitmap(KinectLib *pKinect, int width, int height, const KinectDepthFrame &frame, bool drawSkeleton = false);
    void setSkeletonFrame(const NUI_SKELETON_FRAME &frame);
    void drawSkeletonToBitmap(KinectLib *pKinect, int width, int height, const NUI_SKELETON_FRAME &frame);
    void drawSkeletonToGraphics(Gdiplus::Graphics &graphics, KinectLib *pKinect, int width, int height, const NUI_SKELETON_FRAME &frame);
    void draw3DSkeletonToBitmap(KinectLib *pKinect, int width, int height, const NUI_SKELETON_FRAME &frame);
    void draw3DSkeletonToGraphics(Gdiplus::Graphics &graphics, KinectLib *pKinect, int width, int height, const NUI_SKELETON_FRAME &frame);
    void drawPositionTextToBitmap(KinectLib *pKinect, int width, int height, const NUI_SKELETON_FRAME &frame);
    void drawPositionTextToGraphics(Gdiplus::Graphics &graphics, KinectLib *pKinect, int width, int height, const NUI_SKELETON_FRAME &frame);
    void drawAngleTextToBitmap(KinectLib *pKinect, int width, int height, const NUI_SKELETON_FRAME &frame);
    void drawAngleTextToGraphics(Gdiplus::Graphics &graphics, KinectLib *pKinect, int width, int height, const NUI_SKELETON_FRAME &frame);

    Gdiplus::Bitmap *           getColorBitmap();
    Gdiplus::Bitmap *           getDepthBitmap();
    Gdiplus::Bitmap *           getSkeletonBitmap();
    const NUI_SKELETON_FRAME &  getSkeletonFrame();

public:
    static bool saveImageToFile(Gdiplus::Image *image, const WCHAR *fileName);

private:
    void drawBone(Gdiplus::Graphics &graphics, const NUI_SKELETON_DATA & skeletonData, 
        const NUI_SKELETON_POSITION_INDEX joint0, const NUI_SKELETON_POSITION_INDEX joint1);
    void draw3DBone(const NUI_SKELETON_DATA & skeletonData, 
        const NUI_SKELETON_POSITION_INDEX joint0, const NUI_SKELETON_POSITION_INDEX joint1);
    void drawAngle(Gdiplus::Graphics &graphics, const NUI_SKELETON_DATA & skeletonData, 
        const NUI_SKELETON_POSITION_INDEX joint0,
        const NUI_SKELETON_POSITION_INDEX joint1, 
        const NUI_SKELETON_POSITION_INDEX joint2);

private:
    Gdiplus::Bitmap *       mColorBitmap;
    Gdiplus::Bitmap *       mDepthBitmap;
    Gdiplus::Bitmap *       mDepthFrame;
    Gdiplus::Bitmap *       mSkeletonBitmap;
    Gdiplus::Point          mSkeletonPoints[NUI_SKELETON_POSITION_COUNT];
    SkeletonPoint           mSkeleton3Points[NUI_SKELETON_POSITION_COUNT];
    Vector4                 m3DPoints[NUI_SKELETON_POSITION_COUNT];
    NUI_SKELETON_FRAME      mSkeletonFrame;
    MemoryOpenGL            mMemoryOpenGL;

    Gdiplus::Color          mSkeletonBackColor;
    Gdiplus::Color          mTrackedLineColor;
    Gdiplus::Color          mInferredLineColor;
    Gdiplus::Color          mTrackedEllipseColor;
    Gdiplus::Color          mInferredEllipseColor;

    float                   mLineWidth;
    float                   mHeadDiameter;
    float                   mHandFootDiameter;
    float                   mJointDiameter;
    float                   mScaleRatio;
    float                   mLookAtXAngle;
    float                   mLookAtYAngle;
    Gdiplus::Pen *          mDrawPen;
    Gdiplus::SolidBrush *   mDrawBrush;
    Gdiplus::Font *         mTextFont;
    Gdiplus::SolidBrush *   mTextBrush;
};